/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package net.risesoft.risebi.collection.web.admin;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.risesoft.risebi.collection.model.Application;
import net.risesoft.risebi.collection.model.Attachment;
import net.risesoft.risebi.collection.model.Catalog;
import net.risesoft.risebi.collection.model.Inbox;
import net.risesoft.risebi.collection.model.Outbox;
import net.risesoft.risebi.collection.model.StatisticalObjectTree;
import net.risesoft.risebi.collection.model.StatisticalObjectTreeNode;
import net.risesoft.risebi.collection.model.Trashbin;
import net.risesoft.risebi.collection.model.User;
import net.risesoft.risebi.collection.service.ApplicationManager;
import net.risesoft.risebi.collection.service.AttachmentManager;
import net.risesoft.risebi.collection.service.CatalogManager;
import net.risesoft.risebi.collection.service.DynaBeanManager;
import net.risesoft.risebi.collection.service.ShortMessageManager;
import net.risesoft.risebi.collection.service.StatisticalObjectTreeManager;
import net.risesoft.risebi.collection.service.UserSOManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.struts2extension.Trimable;
import net.risesoft.risebi.commons.util.ExceptionUtil;
import net.risesoft.risebi.commons.util.GUID;
import net.risesoft.risebi.commons.util.JSONUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionInvocation;

/**
 * 
 * 
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @version $Revision$
 * 
 */
@Namespace("/admin/ShortMessageAction")
public class ShortMessageAction extends BaseAction implements Trimable {

	private static final long serialVersionUID = 939053030841747192L;
	private static Log log = LogFactory.getLog(ShortMessageAction.class);
	
	@Action(value = "listOutbox", results = { @Result(name = "success", location = "/admin/shortmessage/outboxList.jsp") })
	public String listOutbox() throws Exception {
		return SUCCESS;
	}
	
	@Action(value = "listInbox", results = { @Result(name = "success", location = "/admin/shortmessage/inboxList.jsp") })
	public String listInbox() throws Exception {
		return SUCCESS;
	}
	
	@Action(value = "listTrashbin", results = { @Result(name = "success", location = "/admin/shortmessage/trashbinList.jsp") })
	public String listTrashbin() throws Exception {
		return SUCCESS;
	}
	
	@Action(value = "viewOutboxShortMessageDetail", results = { @Result(name = "success", location = "/admin/shortmessage/viewoutboxshortmessage.jsp") })
	public String viewOutboxShortMessageDetail() throws Exception {
		outbox = (Outbox) shortMessageManager.getObject(Outbox.class, node);
		return SUCCESS;
	}
	
	@Action(value = "viewInboxShortMessageDetail", results = { @Result(name = "success", location = "/admin/shortmessage/viewinboxshortmessage.jsp") })
	public String viewInboxShortMessageDetail() throws Exception {
//		修改阅读状态和阅读时间
		inbox = (Inbox) shortMessageManager.getObject(Inbox.class, node);
		inbox.setReadStatus(true);
		inbox.setReadTime(new Date());
		shortMessageManager.saveObject(inbox);
		
		return SUCCESS;
	}

	@Action(value = "prepareAdd", results = { @Result(name = "success", location = "/admin/shortmessage/addshortmessage.jsp") })
	public String prepareAdd() throws Exception {
		return SUCCESS;
	}

	@Action(value = "prepareSelectSoItemsFromApp", results = { @Result(name = "success", location = "/admin/shortmessage/selectSoItemsFromApp.jsp") })
	public String prepareSelectSoItemsFromApp() throws Exception {
		List<Application> list = applicationManager.getAppsByServiceWithPermission(this.getDefaultService().getGuid(), this.getSessionUser());

		List<Map<String, String>> newList = new ArrayList<Map<String, String>>();
		for (Application a : list) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("guid", a.getGuid());
			map.put("name", a.getChineseName());
			if (a.getSoTrees().size() > 0) {
				map.put("hastree", "1");
			} else {
				map.put("hastree", "0");
			}

			newList.add(map);
		}
		this.json = JSONUtil.getJsonString(null, null, newList);

		return SUCCESS;
	}

	@Action(value="add",
			results={@Result(name="ajax", type="ajax",params={"contentType","text/html"})}
	)
	public String add() throws Exception {
		LazyDynaBean ldb = new LazyDynaBean();
		try {
//			 首先不管是全部，还是选定的，一律先把 soinstance确定
			List<String> soGuids = new ArrayList<String>();
			List<String> soInstanceGuids = new ArrayList<String>();
			List<String> soInstanceNames = new ArrayList<String>();
			if (beAllReceivers.equals("false")) {
//				 选定的
				String[] soInstanceStrColl = receivers.split("#");
				for(String soInstanceStr:soInstanceStrColl){
					String[] strColl = soInstanceStr.split(",");
					soGuids.add(strColl[0]);
					soInstanceGuids.add(strColl[1]);
					soInstanceNames.add(strColl[2]);
				}
			} else {
//				 全部

			}

//			 将 soinstance对应的user查出，有多个user只需要一个就可以
			List<User> users = userSOManager.getDistinctUserBySoI(soInstanceGuids);
			
//			组成附件列表
			List<Attachment> attachments = new ArrayList<Attachment>();
			if(upload!=null){
				for(int i=0;i<upload.length;i++){
					Attachment attachment = new Attachment();
					attachment.initAttachment(upload[i], uploadFileName[i], new GUID().toString(), Attachment.TYPE_SHORTMESSAGE);
					attachments.add(attachment);
				}
			}
			
			User user = this.getSessionUser();
			outbox.setGuid(new GUID().toString());
			outbox.setSenderGuid(user.getGuid());
			outbox.setSenderName(user.getName());
			outbox.setSendTime(new Date());
			outbox.setDeleted(false);
			outbox.setType(Outbox.TYPE_MANAGERTOSO);
			shortMessageManager.sendShortMessageManagerToSo(outbox, attachments, users, soGuids,soInstanceGuids,soInstanceNames,null);
			
			ldb.set("success", true);
			ldb.set("reason", "发送成功");
		} catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
		}
		this.json = JSONObject.fromObject(ldb).toString();
		return AJAX;
	}

	@Action(value = "refreshJson")
	public String refreshJson() throws Exception {
		try {
			if ("jsonSoTreeByApp".equalsIgnoreCase(this.whichJson)) {
				Application application = applicationManager.getObject(Application.class, node);
				List<StatisticalObjectTree> trees = application.getSoTrees();
				StatisticalObjectTree defaultSot = application.getDefaultSoTree();

				List<Map<String, String>> newList = new ArrayList<Map<String, String>>();
				for (StatisticalObjectTree sot : trees) {
					Map<String, String> map = new HashMap<String, String>();
					map.put("guid", sot.getGuid());
					map.put("name", sot.getName());

					if (defaultSot == null) {
						map.put("defaultsot", "0");
					} else {
						if (sot.getGuid().equals(defaultSot.getGuid())) {
							map.put("defaultsot", "1");
						} else {
							map.put("defaultsot", "0");
						}
					}

					newList.add(map);
				}
				this.json = JSONUtil.getJsonString(null, null, newList);

				return AJAX;
			} else if ("jsonSoTypeByApp".equalsIgnoreCase(this.whichJson)) {
				List<Catalog> lst = catalogManager.getCatalogWithSoByApp(this.node,false);
				List newList = new ArrayList();
				for (Catalog t : lst) {
					if (!t.getSoType().getCode().equalsIgnoreCase("d") && !t.getCode().contains("地区")) {
						Map map = new HashMap();
						map.put("guid", t.getGuid());
						map.put("name", t.getName());
						newList.add(map);
					}
				}
				this.json = JSONUtil.getJsonString(null, null, newList);

				return AJAX;
			} else if ("jsonSoItemsByTree".equalsIgnoreCase(this.whichJson)) {
				StatisticalObjectTree sot = (StatisticalObjectTree) statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, sotGuid);

				if (sot == null)
					return AJAX;

				if ("leftTreeRootNode".equals(this.node)) {
					// 首层结点，则必须满足 item_code 成树状结构，同时需要 item_parentGuid 的内容
					StatisticalObjectTreeNode rootSotNode = sot.getRootNode();
					if (rootSotNode != null) {
						Catalog catalog = rootSotNode.getCatalog();
//						判断层次类型，假如是扁平，则全部取出，否则就根据是否邻接或者分层来显示第一层
						Integer hierarchicalType = catalog.getHierarchicalType();
						hierarchicalType = hierarchicalType==null?0:hierarchicalType;
						
						String tableName = rootSotNode.getTableName();
						if(hierarchicalType==0){
//							扁平
							Map<String,Object> map = dynaBeanManager.getPagedData(tableName, 0, 0, "tabindex", "asc");
							List list = (List) map.get("list");
							
							JSONArray jsonArray = new JSONArray();
							for (int i = 0; i < list.size(); i++) {
								Map innerMap = (Map) list.get(i);

								JSONObject jsonObj = new JSONObject();
								jsonObj.element("id", innerMap.get("item_guid"));
								jsonObj.element("text", innerMap.get("item_name"));
								jsonObj.element("sotNodeGuid", rootSotNode.getGuid());
								jsonObj.element("singleClickExpand", true);
								jsonObj.element("leaf", true);
								jsonArray.add(jsonObj);
							}

							this.json = jsonArray.toString();
						}else if(hierarchicalType==1){
//							邻接模型
							List list = dynaBeanManager.getFirstScopeSoItems(tableName);
							JSONArray jsonArray = new JSONArray();
							for (int i = 0; i < list.size(); i++) {
								Map innerMap = (Map) list.get(i);

								JSONObject jsonObj = new JSONObject();
								jsonObj.element("id", innerMap.get("item_guid"));
								jsonObj.element("text", innerMap.get("item_name"));
								jsonObj.element("sotNodeGuid", rootSotNode.getGuid());
								jsonObj.element("singleClickExpand", true);
								jsonObj.element("leaf", false);
								jsonArray.add(jsonObj);
							}

							this.json = jsonArray.toString();
						}else{
//							分层编码
							String segmentslength = catalog.getSegmentslength();
							String[] segments = segmentslength.split(",");
							
							List list = dynaBeanManager.getCodeHierachicalSoItems(tableName, null, Integer.valueOf(segments[0]));
							JSONArray jsonArray = new JSONArray();
							for (int i = 0; i < list.size(); i++) {
								Object[] object = (Object[]) list.get(i);

								JSONObject jsonObj = new JSONObject();
								jsonObj.element("id", object[0]);
								jsonObj.element("text", object[1]);
								jsonObj.element("sotNodeGuid", rootSotNode.getGuid());
								jsonObj.element("singleClickExpand", true);
								jsonObj.element("leaf", false);
								jsonArray.add(jsonObj);
							}

							this.json = jsonArray.toString();
						}
					}
				} else {
					// 下层结点，扁平没有下层，邻接和分层编码有下层
					StatisticalObjectTreeNode rootSotNode = sot.getRootNode();
					Catalog catalog = rootSotNode.getCatalog();
//					判断层次类型
					Integer hierarchicalType = catalog.getHierarchicalType();
					hierarchicalType = hierarchicalType==null?0:hierarchicalType;
					String tableName = rootSotNode.getTableName();
					if(hierarchicalType==1){
//						邻接
						List list = dynaBeanManager.getNextScopeSoItems(tableName, node);
						
						JSONArray jsonArray = new JSONArray();
						for (int i = 0; i < list.size(); i++) {
							Map objMap = (Map) list.get(i);

							JSONObject jsonObj = new JSONObject();
							jsonObj.element("id", objMap.get("item_guid"));
							jsonObj.element("text", objMap.get("item_name"));
							jsonObj.element("sotNodeGuid", rootSotNode.getGuid());
							jsonObj.element("singleClickExpand", true);
							jsonObj.element("leaf", false);
							jsonArray.add(jsonObj);
						}

						this.json = jsonArray.toString();
					}else{
//						分层编码
						Map soInstance = dynaBeanManager.getSoInstance(catalog.getGuid(), node);
						String preCode = (String) soInstance.get("item_code");
						
						String segmentslength = catalog.getSegmentslength();
						String[] segments = segmentslength.split(",");
						
						int codeCount = 0;
						int selfCodeLength = 0;
						for(int i=0;i<segments.length;i++){
							int iTemp = Integer.valueOf(segments[i]);
							codeCount += iTemp;
							if(codeCount==preCode.length()){
								selfCodeLength = Integer.valueOf(segments[i+1]);
								break;
							}
						}
						
						List list = dynaBeanManager.getCodeHierachicalSoItems(tableName, preCode, selfCodeLength);
						
						JSONArray jsonArray = new JSONArray();
						for (int i = 0; i < list.size(); i++) {
							Object[] object = (Object[]) list.get(i);

							JSONObject jsonObj = new JSONObject();
							jsonObj.element("id", object[0]);
							jsonObj.element("text", object[1]);
							jsonObj.element("sotNodeGuid", rootSotNode.getGuid());
							jsonObj.element("singleClickExpand", true);
							jsonObj.element("leaf", false);
							jsonArray.add(jsonObj);
						}

						this.json = jsonArray.toString();
					}
				}
			} else if ("jsonSoItems".equalsIgnoreCase(this.whichJson)) {
				if (sotGuid == null || sotGuid.equals("")) {
					this.json = "[]";
					return AJAX;
				}
				StatisticalObjectTree sot = (StatisticalObjectTree) statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, sotGuid);

				// int scopeNumber = sot.getScopeNumber(currentSotNodeGuid);
				StatisticalObjectTreeNode sotNode = sot.getSotNodeBySotNodeGuid(currentSotNodeGuid);

				List<StatisticalObjectTreeNode> children = sotNode.getChildren();
				
				if(children.size()<1){
					this.json = "[]";
					return AJAX;
				}
					
				List<String> sqlList = new ArrayList<String>();
				for (StatisticalObjectTreeNode sSotNode : children) {
					Map soInstanceMap = dynaBeanManager.getSoInstance(sotNode.getSoGuid(), soInstanceGuid);
					String parentColumnName = sSotNode.getParentColumnName().toLowerCase();
					String value = (String) soInstanceMap.get(parentColumnName);
					
					String tableName = sSotNode.getTableName();
					
					String selfColumnName = sSotNode.getSelfColumnName();
					if (selfColumnName == null || selfColumnName.equals("")) {
						throw new Exception("没有对树进行正确设置");
					}

					String sql = "select catalog_guid,item_guid,item_name from " + tableName + " where " + selfColumnName + "='" + value + "'";

					if (sotNodeName != null && !sotNodeName.equals("")) {
						sql += " and item_name like '%" + sotNodeName + "%'";
					}

					sqlList.add(sql);
				}

				Map<String, Object> map = dynaBeanManager.getUnionPagedSoInstances(sqlList, start, limit);
				List originalList = (List) map.get("list");
				List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
				for (int i = 0; i < originalList.size(); i++) {
					Object[] objColl = (Object[]) originalList.get(i);
					Map<String, Object> newMap = new HashMap<String, Object>();
					newMap.put("catalogGuid", objColl[0]);
					newMap.put("item_guid", objColl[1]);
					newMap.put("item_name", objColl[2]);

					if (this.active_node_id == null || this.active_node_id.equals("")) {
						newMap.put("item_parentguid", "");
					} else {
						newMap.put("item_parentguid", active_node_id);
					}

					for (int j = 0; j < children.size(); j++) {
						StatisticalObjectTreeNode sSotNode = children.get(j);
						if (sSotNode.getCatalog().getGuid().equals(objColl[0])) {
							newMap.put("from_name", sSotNode.getName());
							newMap.put("sotNode_Guid", sSotNode.getGuid());

							// 判断一下有无后续结点
							List<StatisticalObjectTreeNode> alist = sSotNode.getChildren();
							if (alist.size() > 0) {
								newMap.put("isleaf", false);
							} else {
								newMap.put("isleaf", true);
							}

							break;
						}
					}

					newList.add(newMap);
				}

				map.put("list", newList);

				this.json = JSONUtil.getJsonString(null, null, map);
			}else if ("jsonOutboxList".equalsIgnoreCase(this.whichJson)) {
				User user = this.getSessionUser();
				Map<String,?> map = shortMessageManager.getOutboxes(user.getGuid(), start, limit, false);
				this.json = JSONUtil.getJsonString("exclude", "content", map);
			}else if ("jsonInboxRedundanceList".equalsIgnoreCase(this.whichJson)) {
				Map<String,?> map = shortMessageManager.getInboxRedundanceByOutbox(node, start, limit); 
				this.json = JSONUtil.getJsonString("exclude", "outbox", map);
			}else if ("jsonAttachmentsList".equalsIgnoreCase(this.whichJson)) {
				List<Attachment> list = attachmentManager.getAttachments(node, false);
				this.json = JSONUtil.getJsonString("include", "guid,name,size", list);
			}else if("jsonInboxList".equalsIgnoreCase(this.whichJson)) {
				User user = this.getSessionUser();
				Map<String,?> map = shortMessageManager.getInboxes(user.getGuid(), start, limit, false);
				this.json = JSONUtil.getJsonString("exclude", "outbox", map);
			}else if("jsonTrashbinList".equalsIgnoreCase(this.whichJson)) {
				User user = this.getSessionUser();
				Map<String,?> map = shortMessageManager.getTrashbin(user.getGuid(), start, limit);
				this.json = JSONUtil.getJsonString(null, null, map);
			}
		} catch (Exception e) {
			this.json = "[]";
			log.error(ExceptionUtil.transformException(e));
		}

		return AJAX;
	}
	
	@Action(value = "remove")
	public String remove() throws Exception {
		LazyDynaBean ldb = new LazyDynaBean();
		try {
			if(sourceType==Trashbin.SOURCETYPE_OUTBOX){
				shortMessageManager.moveToTrashBinFromOutbox(node);
			}else{
				shortMessageManager.moveToTrashBinFromInbox(node);
			}
			
			ldb.set("success", true);
		}catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
		}
		this.json = JSONObject.fromObject(ldb).toString();
		return AJAX;
	}
	
	@Action(value = "recover")
	public String recover() throws Exception {
		LazyDynaBean ldb = new LazyDynaBean();
		try {
			shortMessageManager.recover(node);
			
			ldb.set("success", true);
		}catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
		}
		this.json = JSONObject.fromObject(ldb).toString();
		return AJAX;
	}
	
	@Action(value = "clear")
	public String clear() throws Exception {
		LazyDynaBean ldb = new LazyDynaBean();
		try {
			if(node==null || node.equals("")){
				User user = this.getSessionUser();
				shortMessageManager.clearAllShortMessages(user.getGuid());
			}else{
				shortMessageManager.clearAShortMessage(node);
			}
			
			ldb.set("success", true);
		}catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
		}
		this.json = JSONObject.fromObject(ldb).toString();
		return AJAX;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seenet.risesoft.risebi.commons.struts2extension.Trimable#afterTrim(com.
	 * opensymphony.xwork2.ActionInvocation)
	 */
	public void afterTrim(ActionInvocation invocation) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seenet.risesoft.risebi.commons.struts2extension.Trimable#preTrim(com.
	 * opensymphony.xwork2.ActionInvocation)
	 */
	public boolean preTrim(ActionInvocation invocation) {
		return true;
	}

	private ApplicationManager applicationManager;
	private StatisticalObjectTreeManager statisticalObjectTreeManager;
	private DynaBeanManager dynaBeanManager;
	private CatalogManager catalogManager;
	private UserSOManager userSOManager;
	private ShortMessageManager shortMessageManager;
	private AttachmentManager attachmentManager;

	private String sotGuid;
	private String firstIn;
	private String soInstanceGuid;
	private String currentSotNodeGuid;
	private String sotNodeName;
	private Outbox outbox;
	private Inbox inbox;
	private String receivers;
	private String beAllReceivers;
	private File[] upload;
    private String[] uploadFileName;
    private int sourceType;
    
    public int getSourceType() {
		return sourceType;
	}

	public void setSourceType(int sourceType) {
		this.sourceType = sourceType;
	}

	public Inbox getInbox() {
		return inbox;
	}

	public void setInbox(Inbox inbox) {
		this.inbox = inbox;
	}

    public Outbox getOutbox() {
		return outbox;
	}

	public void setOutbox(Outbox outbox) {
		this.outbox = outbox;
	}
    
	public File[] getUpload() {
		return upload;
	}

	public void setUpload(File[] upload) {
		this.upload = upload;
	}

	public String[] getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String[] uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getReceivers() {
		return receivers;
	}

	public void setReceivers(String receivers) {
		this.receivers = receivers;
	}

	public String getBeAllReceivers() {
		return beAllReceivers;
	}

	public void setBeAllReceivers(String beAllReceivers) {
		this.beAllReceivers = beAllReceivers;
	}

	public String getSotNodeName() {
		return sotNodeName;
	}

	public void setSotNodeName(String sotNodeName) {
		this.sotNodeName = sotNodeName;
	}

	public String getSoInstanceGuid() {
		return soInstanceGuid;
	}

	public void setSoInstanceGuid(String soInstanceGuid) {
		this.soInstanceGuid = soInstanceGuid;
	}

	public String getCurrentSotNodeGuid() {
		return currentSotNodeGuid;
	}

	public void setCurrentSotNodeGuid(String currentSotNodeGuid) {
		this.currentSotNodeGuid = currentSotNodeGuid;
	}

	public String getFirstIn() {
		return firstIn;
	}

	public void setFirstIn(String firstIn) {
		this.firstIn = firstIn;
	}

	public String getSotGuid() {
		return sotGuid;
	}

	public void setSotGuid(String sotGuid) {
		this.sotGuid = sotGuid;
	}

	public void setCatalogManager(CatalogManager catalogManager) {
		this.catalogManager = catalogManager;
	}

	public void setDynaBeanManager(DynaBeanManager dynaBeanManager) {
		this.dynaBeanManager = dynaBeanManager;
	}

	public void setStatisticalObjectTreeManager(StatisticalObjectTreeManager statisticalObjectTreeManager) {
		this.statisticalObjectTreeManager = statisticalObjectTreeManager;
	}

	public void setApplicationManager(ApplicationManager applicationManager) {
		this.applicationManager = applicationManager;
	}

	public void setUserSOManager(UserSOManager userSOManager) {
		this.userSOManager = userSOManager;
	}
	
	public void setShortMessageManager(ShortMessageManager shortMessageManager) {
		this.shortMessageManager = shortMessageManager;
	}
	
	public void setAttachmentManager(AttachmentManager attachmentManager) {
		this.attachmentManager = attachmentManager;
	}
}
